#include "tools.h"

tools::tools(QWidget *par): QWidget(par){

	QVBoxLayout *layout = new QVBoxLayout;
	
	helpAssistant = qobject_cast<bakalarka *>(parent())->getAssistant();
	vLayout = new QVBoxLayout;
	setLayout(layout);
	layout->addLayout(vLayout, 0);
	createConfirm(layout);
	createHelp();

}

void tools::helpClicked(){

	showHelp();

}

void tools::createHelp(){

	QToolButton *button = new QToolButton;
	QHBoxLayout *hLayout = new QHBoxLayout;
	QLabel *gap = new QLabel;
	
	button->setIcon(QIcon(":img/help-sub.png"));
	button->setToolTip(tr("Zobrazí nápovědu"));
	button->resize(10, 10);
	vLayout->addLayout(hLayout);
	hLayout->addWidget(gap, 1);
	hLayout->addWidget(button, 0, Qt::AlignRight);
	
	connect(button, SIGNAL(clicked()), this, SLOT(helpClicked()));

}

void tools::showHelp(){

	

}

void tools::createConfirm(QVBoxLayout *lay){
	
	QHBoxLayout *layout = new QHBoxLayout;
	QPushButton *ok = new QPushButton(tr("Potvrdit"));
	QPushButton *cancel = new QPushButton(tr("Zrušit"));
	QWidget *gap = new QWidget;
	
	layout->addWidget(gap, 1, Qt::AlignRight);
	layout->addWidget(cancel, 0, Qt::AlignRight);
	layout->addWidget(ok, 0, Qt::AlignRight);
	lay->addWidget(gap, 1);
	lay->addLayout(layout, 0);
	connect(ok, SIGNAL(clicked()), this, SLOT(okClicked()));
	connect(cancel, SIGNAL(clicked()), this, SLOT(cancelClicked()));
	
}

const QWidget *tools::getTopWidget() const{
	
	const QWidget *parent = this;
	
	while(parent->parentWidget()){
		parent = parent->parentWidget();
	}
	return parent;

}

drawArea *tools::getDrawArea() const{

	const bakalarka *topWidget = dynamic_cast<const bakalarka *>(getTopWidget());
	return topWidget->getDrawArea();

}

void tools::okClicked(){

	drawArea *area = getDrawArea();
	if(area)
		area->logicFlush();
	clear();

}

void tools::cancelClicked(){

	drawArea *area = getDrawArea();
	if(area)
		area->logicRestore();
	clear();

}


translateTool::translateTool(QWidget *parent): tools(parent){

	createIncrement();
	createNavigation();
	createInfo();
	connect(this, SIGNAL(info()), this, SLOT(updateInfo()));

}

void translateTool::showHelp(){

	helpAssistant->showKeyword("translate");

}

void translateTool::createIncrement(){

	QFormLayout *layout = new QFormLayout;
	
	layout->setFormAlignment(Qt::AlignLeft);
	increment = new QDoubleSpinBox();
        increment->setRange(-9999.99, 9999.99);
        increment->setDecimals(3);
	vLayout->addLayout(layout, 0);
	layout->addRow(tr("Inkrement: "), increment);

}

void translateTool::createNavigation(){

	QGridLayout *layout = new QGridLayout;
	QPushButton *left = new QPushButton(QIcon(":img/left.png"), tr(""));
	QPushButton *right = new QPushButton(QIcon(":img/right.png"), tr(""));
	QPushButton *up = new QPushButton(QIcon(":img/up.png"), tr(""));
	QPushButton *down = new QPushButton(QIcon(":img/down.png"), tr(""));
	QLabel *label = new QLabel(tr("Směr posunutí"));

	layout->setContentsMargins(0, 10, 0, 0);
	layout->addWidget(up, 0, 1, Qt::AlignHCenter);
	layout->addWidget(left, 1, 0, Qt::AlignRight);
	layout->addWidget(label, 1, 1);
	layout->addWidget(right, 1, 2, Qt::AlignLeft);
	layout->addWidget(down, 2, 1, Qt::AlignHCenter);
	vLayout->addLayout(layout, 0);
	
	connect(left, SIGNAL(clicked()), this, SLOT(moveLeft()));
	connect(right, SIGNAL(clicked()), this, SLOT(moveRight()));
	connect(up, SIGNAL(clicked()), this, SLOT(moveUp()));
	connect(down, SIGNAL(clicked()), this, SLOT(moveDown()));

}

void translateTool::createInfo(){

	QFormLayout *layout = new QFormLayout;
	
	layout->setContentsMargins(0, 10, 0, 0);
	layout->setFormAlignment(Qt::AlignLeft);
	diffXValue = new QLabel(tr("%1").arg(diff.x()));
	diffYValue = new QLabel(tr("%1").arg(diff.y())); 
	distance = new QLabel(tr("%1").arg(getDistance(diff))); 
	layout->addRow(tr("Rozdil X : "), diffXValue);
	layout->addRow(tr("Rozdil Y : "), diffYValue);
	layout->addRow(tr("Vzdálenost : "), distance);
	
	vLayout->addLayout(layout, 0);

}

float translateTool::getDistance(QPointF &point){

	float x, y;
	
	x = point.x();
	y = point.y();
	return sqrt(x * x + y * y);

}

void translateTool::moveUp(){

	move(0, increment->value());

}

void translateTool::moveDown(){

	move(0, -increment->value());

}

void translateTool::moveLeft(){

	move(-increment->value(), 0);

}

void translateTool::moveRight(){

	move(increment->value(), 0);

}

void translateTool::move(float x, float y){

	drawArea *area = getDrawArea();
	QPointF point(x, y);
	
	if(area){
		area->logicTranslate(point);
		diff.setX(diff.x() + x);
		diff.setY(diff.y() + y);
		emit info();
	}

}

void translateTool::updateInfo(){

	diffXValue->setText(tr("%1").arg(diff.x()));
	diffYValue->setText(tr("%1").arg(diff.y()));
	distance->setText(tr("%1").arg(getDistance(diff)));

}

void translateTool::clear(){

	diff.setX(0);
	diff.setY(0);
	increment->setValue(0);
	emit info();

}

rotateTool::rotateTool(QWidget *parent): tools(parent){

	rotateAngle = 0;
	createIncrement();
	createNavigation();
	createInfo();
	connect(this, SIGNAL(info()), this, SLOT(updateInfo()));

}

void rotateTool::showHelp(){

	helpAssistant->showKeyword("rotate");

}

QString rotateTool::getAngle(float angle) const{

	int degrees = floor(angle);
	int minutes =  floor((angle - degrees) * 60);
	int seconds = floor((((angle - degrees) * 60) - minutes) * 60);
	QString string(tr("%1° %2' %3\""));
	return string.arg(degrees).arg(minutes).arg(seconds);

}

QString rotateTool::getRad(float angle) const{
	
	return QString(tr("%1").arg(M_PI / 180.0 * angle));
	
}

void rotateTool::incrementChanged(double value){

	diffAngleValue->setText(getAngle(value));

}

void rotateTool::createIncrement(){

	QFormLayout *layout = new QFormLayout;
	
	diffAngleValue = new QLabel(getAngle(rotateAngle));
	layout->setFormAlignment(Qt::AlignLeft);
	increment = new QDoubleSpinBox();
	increment->setDecimals(3);
	increment->setRange(0.0, 360.0);
	vLayout->addLayout(layout, 0);
	layout->addRow(tr("Úhel : "), increment);
	layout->addRow(tr("Úhel : "), diffAngleValue);
	connect(increment, SIGNAL(valueChanged(double)), this, SLOT(incrementChanged(double)));

}

void rotateTool::createNavigation(){

	QGridLayout *layout = new QGridLayout;
	QPushButton *clock = new QPushButton(QIcon(":img/clock.png"), tr(""));
	QPushButton *counter = new QPushButton(QIcon(":img/counter.png"), tr(""));
	QLabel *label = new QLabel(tr("Směr otáčení :"));
	
	layout->setContentsMargins(0, 10, 0, 0);
	layout->addWidget(label, 0, 0);
	layout->addWidget(counter, 0, 1);
	layout->addWidget(clock, 0, 2);
	vLayout->addLayout(layout);
	connect(clock, SIGNAL(clicked()), this, SLOT(clockwise()));
	connect(counter, SIGNAL(clicked()), this, SLOT(counterClockwise()));

}

QString rotateTool::getPoint(QPointF &point) const{
	
	QString string("(%1, %2)");
	
	return string.arg(point.x()).arg(point.y());

}

void rotateTool::createInfo(){
	
	QFormLayout *layout = new QFormLayout;
	
	pointLabel = new QLabel;
	value = new QLabel;
	angleValue = new QLabel;
	radValue = new QLabel;
	layout->setContentsMargins(0, 10, 0, 0);
	layout->addRow(tr("Bod otáčení : "), pointLabel);
	layout->addRow(tr("Celkem stupně : "), value);
	layout->addRow(tr("Celkem stupně : "), angleValue);
	layout->addRow(tr("Celkem radiány : "), radValue);
	vLayout->addLayout(layout);
	updateInfo();
	
}

void rotateTool::updateInfo(){

	pointLabel->setText(getPoint(middle));
	value->setText(tr("%1").arg(rotateAngle));
	angleValue->setText(getAngle(rotateAngle));
	radValue->setText(getRad(rotateAngle));

}

void rotateTool::clear(){

	increment->setValue(0);
	rotateAngle = 0;
	emit info();

}

void rotateTool::clockwise(){

	rotate(-increment->value());

}

void rotateTool::counterClockwise(){

	rotate(increment->value());

}

void rotateTool::rotate(float angle){

	drawArea *area = getDrawArea();
	float rad = M_PI / 180 * angle;
	
	if(area){
		rotateAngle += angle;
		area->logicRotate(middle, rad);
		emit info();
	}
	
}

void rotateTool::setMiddle(QPointF &point){

	middle = point;
	info();

}

toolTool::toolTool(QWidget *parent): tools(parent){

	createIncrement();
	createNavigation();
	createInfo();
	connect(this, SIGNAL(info()), this, SLOT(updateInfo()));

}

void toolTool::createIncrement(){

	QFormLayout *layout = new QFormLayout;

	toolIncrement = new QDoubleSpinBox();
	zIncrement = new QDoubleSpinBox();
	toolIncrement->setDecimals(3);
	zIncrement->setDecimals(3);
	toolIncrement->setRange(-1000.0, 1000.0);
	zIncrement->setRange(-1000.0, 1000.0);
	layout->addRow(tr("Nástroj : "), toolIncrement);
	layout->addRow(tr("Výška : "), zIncrement);
	vLayout->addLayout(layout);

}

void toolTool::createNavigation(){

	QGridLayout *layout = new QGridLayout;
	QPushButton *preview = new QPushButton(tr("Použít"));
	QLabel *label = new QLabel(tr("Zobrazit náhled : "));
	QLabel *checkLabel = new QLabel(tr("Použít pro posun : "));
	QLabel *checkCommonLabel = new QLabel(tr("Společný bod: "));
	
	check = new QCheckBox;
	commonCheck = new QCheckBox;
	check->setChecked(true);
	layout->setContentsMargins(0, 10, 0, 0);
	layout->addWidget(checkLabel, 0, 0);
	layout->addWidget(check, 0, 1, Qt::AlignLeft);
	layout->addWidget(checkCommonLabel, 1, 0);
	layout->addWidget(commonCheck, 1, 1, Qt::AlignLeft);
	layout->addWidget(label, 2, 0);
	layout->addWidget(preview, 2, 1, Qt::AlignLeft);
	vLayout->addLayout(layout);
	connect(preview, SIGNAL(clicked()), this, SLOT(goToolTransform()));

}

void toolTool::createInfo(){

	QFormLayout *layout = new QFormLayout;
	
	toolLabel = new QLabel;
	zLabel = new QLabel;
	layout->setContentsMargins(0, 10, 0, 0);
	layout->addRow(tr("Posunutí nástroje : "), toolLabel);
	layout->addRow(tr("Posunutí osy z : "), zLabel);

	vLayout->addLayout(layout);
	updateInfo();

}

void toolTool::clear(){

	toolIncrement->setValue(0);
	zIncrement->setValue(0);
	emit info();

}

void toolTool::showHelp(){

	helpAssistant->showKeyword("tool");

}

void toolTool::updateInfo(){

	toolLabel->setText(tr("%1").arg(toolIncrement->value()));
	zLabel->setText(tr("%1").arg(zIncrement->value()));

}

void toolTool::goToolTransform(){

	drawArea *area = getDrawArea();
	
	if(area){
		area->logicTool(toolIncrement->value(), 
			zIncrement->value(), 
			check->isChecked(), 
			commonCheck->isChecked());
		emit info();
	}

}

morphTool::morphTool(QWidget *parent): tools(parent){
	
	fullDistance = 0;
	createIncrement();
	createNavigation();
	createInfo();
	
}

void morphTool::createIncrement(){
	
	QFormLayout *layout = new QFormLayout;
	
	morphIncrement = new QDoubleSpinBox;
	morphIncrement->setDecimals(3);
	layout->addRow(tr("Inkrement: "), morphIncrement);
	vLayout->addLayout(layout);
	
}

void morphTool::createNavigation(){

	QPixmap pixPrev(":img/morph-prev.png");
	QPixmap pixNext(":img/morph-next.png");
	QLabel *pixLabelPrev = new QLabel;
	QLabel *pixLabelNext = new QLabel;
	QGridLayout *layout = new QGridLayout;
	QLabel *direction = new QLabel(tr("Směr: "));
	QLabel *order = new QLabel(tr("Pořadí: "));
	QLabel *commonLabel = new QLabel(tr("Společný bod: "));
	QPushButton *minus = new QPushButton(QIcon(":img/left.png"), tr(""));
	QPushButton *plus = new QPushButton(QIcon(":img/right.png"), tr(""));
	QButtonGroup *group = new QButtonGroup(this);
	
	commonPoint = new QCheckBox;	
	pixLabelPrev->setPixmap(pixPrev);
	pixLabelNext->setPixmap(pixNext);
	layout->setContentsMargins(0, 10, 0, 0);
	behind = new QRadioButton;
	ahead = new QRadioButton;
	ahead->setChecked(true);
	group->addButton(behind);
	group->addButton(ahead);
	layout->addWidget(direction, 0, 0);
	layout->addWidget(minus, 0, 1);
	layout->addWidget(plus, 0, 2);
	layout->addWidget(pixLabelPrev, 1, 1, Qt::AlignCenter);
	layout->addWidget(pixLabelNext, 1, 2, Qt::AlignCenter);
	layout->addWidget(order, 2, 0);
	layout->addWidget(behind, 2, 1, Qt::AlignCenter);
	layout->addWidget(ahead, 2, 2,  Qt::AlignCenter);
	layout->addWidget(commonLabel, 3, 0);
	layout->addWidget(commonPoint, 3, 1, Qt::AlignCenter);
	vLayout->addLayout(layout);
	connect(minus, SIGNAL(clicked()), this, SLOT(minusClicked()));
	connect(plus, SIGNAL(clicked()), this, SLOT(plusClicked()));

}

void morphTool::plusClicked(){

	morph(morphIncrement->value());

}

void morphTool::minusClicked(){

	morph(-morphIncrement->value());

}

void morphTool::morph(float d){

	drawArea *area = getDrawArea();
	
	if(area){
		bool next;
		
		next = behind->isChecked() ? false : true;
		if(area->logicMorph(d, morphTransformation::DISTANCE, next, commonPoint->isChecked()))
			fullDistance += d;
	}
	updateInfo();

}

void morphTool::updateInfo(){

	distance->setText(tr("%1").arg(fullDistance));
	drawArea *area = getDrawArea();
	
	if(area){
		gTypeGo *go = area->getControl().getClickedGTypeGo();
		if(go)
			point0->setText(tr("(%1, %2)").arg((*go)[0]).arg((*go)[1]));
		else
			point0->setText(tr("(0, 0)"));
	}
	else
		point0->setText(tr("(0, 0)"));

}

void morphTool::createInfo(){

	QFormLayout *layout = new QFormLayout;
	
	layout->setContentsMargins(0, 10, 0, 0);
	distance = new QLabel(tr("0"));
	point0 = new QLabel(tr("(0, 0)"));
	layout->addRow(tr("Vzdálenost: "), distance);
	layout->addRow(tr("Pracovni bod: "), point0);
	vLayout->addLayout(layout);

}


void morphTool::showHelp(){

	helpAssistant->showKeyword("morph");

}

void morphTool::clear(){

	fullDistance = 0;
	updateInfo();

}
